package com.zuo.seckilldemo.controller;


import com.alibaba.fastjson.JSON;
import com.zuo.seckilldemo.entity.Order;
import com.zuo.seckilldemo.entity.SeckillMessage;
import com.zuo.seckilldemo.entity.User;
import com.zuo.seckilldemo.rabbitmq.MQSender;
import com.zuo.seckilldemo.result.CodeMsg;
import com.zuo.seckilldemo.result.Result;
import com.zuo.seckilldemo.service.GoodsService;
import com.zuo.seckilldemo.service.OrderInfoService;
import com.zuo.seckilldemo.utils.UserThreadLocal;
import com.zuo.seckilldemo.vo.GoodsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/seckill")
@Slf4j
public class SeckillController implements InitializingBean {
    @Autowired
    private MQSender mqSender;
    @Autowired
    private GoodsService goodsService;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private OrderInfoService orderInfoService;
    
    private Map<Long,Boolean> EmptyStockMap = new HashMap<>();
    @PostMapping("/{path}/do_seckill")
    @ResponseBody
    public Result do_Seckill(Long goodsId, @PathVariable String path){
        User user = UserThreadLocal.get();
        if (user ==null){
            return Result.error(CodeMsg.SESSION_ERROR );
        }
        ValueOperations valueOperations = redisTemplate.opsForValue();
        System.out.println(path);
        System.out.println(valueOperations.get("seckillPath:" + user.getId()));
        if (!path.equals(valueOperations.get("seckillPath:"+user.getId())) ||StringUtils.isEmpty(path)){
            return Result.error(CodeMsg.ILLEGAL_REQUEST);
        }
        Order order1 = (Order) valueOperations.get("userId:" + user.getId() + "_goodsId:" + goodsId);
        if (order1!=null){
            return Result.error(CodeMsg.REPEATE_SECKILL);
        }
        if (EmptyStockMap.get(goodsId)==true){
            System.out.println(EmptyStockMap.get(goodsId));
            return Result.error(CodeMsg.EMPTY_STOCK);
        }

        Long stock = valueOperations.decrement("seckillGoods:" + goodsId);
        if (stock<0){
            EmptyStockMap.put(goodsId,true);
            valueOperations.set("stockEmpty"+goodsId,1);
            valueOperations.increment("seckillGoods:" + goodsId);
            return Result.error(CodeMsg.SECKILL_OVER);
        }
        SeckillMessage seckillMessage = new SeckillMessage(user, goodsId);
        mqSender.send(JSON.toJSONString(seckillMessage));

        return Result.success(200,"等待中",null);
        
//
//        OrderInfo order = orderInfoService.seckill(user,goodsVo);
//        return Result.success(200,"成功",order);
    }
    @RequestMapping("/path")
    @ResponseBody
    public Result getPath(Long goodsId){
        User user = UserThreadLocal.get();
        if (user ==null) return Result.error(CodeMsg.SESSION_ERROR);
        String path = orderInfoService.createPath(user,goodsId);
        return Result.success(200,"成功",path);
    }
    @RequestMapping("/getResult")
    @ResponseBody
    public Result getResult(Long goodsId){
        User user = UserThreadLocal.get();
        if (user ==null) return Result.error(CodeMsg.SESSION_ERROR);
        Long orderInfoId = orderInfoService.getResult(user,goodsId);
        System.out.println(orderInfoId);
        return Result.success(200,"",orderInfoId);
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        List<GoodsVo> list = goodsService.findGoodsVo();
        if (list.isEmpty()) {
            return;
        }
        list.forEach(goodsVo -> {
            System.out.println(goodsVo);
            redisTemplate.opsForValue().set("seckillGoods:"+goodsVo.getId(),goodsVo.getStockCount());
            EmptyStockMap.put(goodsVo.getId(),false);
        });
        
    }
}
